import React from 'react';
import i18n from 'i18n-js';
import Taro from '@tarojs/taro';
import { View, Image } from '@tarojs/components';
import { toJS, reaction } from 'mobx';
import DeviceCapacity, {
  INewDevice,
  isDeviceCapacityChange,
  CapacityState,
  sortCapacityUse,
  IDeviceCapacity,
  DeviceCapacityName,
} from '@/models/deviceList/deviceCapacity';
import deviceListModel from '@/models/deviceList';
import { ThemeCompetent } from '@/utils/DarkMode';
import DeviceStatusModal, { IDeviceStatusModalProps } from '@/components/Modal/DeviceStatusModal';
import DeviceOffline from '@/components/Modal/DeviceOffline';
import DeviceLoading from '@/components/Modal/DeviceLoading';
import FrameImage from '@/components/FrameImage';
import { isSameDevice } from '@/utils';
import bleGif1 from '@/assets/images/ble_gif_1.png';
import bleGif2 from '@/assets/images/ble_gif_2.png';
import bleGif3 from '@/assets/images/ble_gif_3.png';
import wifiGif1 from '@/assets/images/wifi_gif_1.png';
import wifiGif2 from '@/assets/images/wifi_gif_2.png';
import wifiGif3 from '@/assets/images/wifi_gif_3.png';
import gprsGif1 from '@/assets/images/gprs_gif_1.png';
import gprsGif2 from '@/assets/images/gprs_gif_2.png';
import gprsGif3 from '@/assets/images/gprs_gif_3.png';
import bleFailIcon from '@/assets/images/ble_fail.png';
import bleOfflineIcon from '@/assets/images/ble_offline.png';
import wifiFailIcon from '@/assets/images/wifi_fail.png';
import wifiOfflineIcon from '@/assets/images/wifi_offline.png';
import gprsFailIcon from '@/assets/images/gprs_fail.png';
import gprsOfflineIcon from '@/assets/images/gprs_offline.png';
import offlineIcon from '@/assets/images/img_offline.png';
import TipItem from './TipItem';
import { getConfig, isGPRS } from '@/config/product';

interface IProps {
  device: INewDevice;
}

interface IState extends IDeviceStatusModalProps {
  name: string; // 当前弹窗是哪种能力
  canOver: boolean; // 弹窗能否被覆盖
}

const blueColor = '#016ef9';

@ThemeCompetent
class DeviceCapacityModal extends React.Component<IProps, IState> {
  state = {
    buttons: [],
    visible: false,
    title: '',
    content: '',
    image: null,
    name: '',
    canOver: true,
  };

  deviceReaction: any;

  oldDevice: INewDevice; // 记录旧的设备数据

  oldCapacity: IDeviceCapacity;

  constructor(props: IProps) {
    super(props);
    this.oldDevice = { ...props.device };
    this.oldCapacity = this.getDeviceCapacity(this.oldDevice);
  }

  getButtons = () => {
    return [
      {
        text: i18n.t('EXIT'),
        color: blueColor,
        onClick: () => {
          Taro.navigateBack({ delta: 1 });
        },
      },
      {
        text: i18n.t('RETRY'),
        color: blueColor,
        onClick: this.retryClick,
      },
    ];
  };

  getDeviceCapacity = (device: INewDevice) => {
    if (device.isVirtual) {
      return new DeviceCapacity({
        name: DeviceCapacityName.wifi,
        state: CapacityState.offline,
        netStatus: 0,
        level: 0,
      });
    }
    if (device.bleCapacity && device.wifiCapacity) {
      // 双模的话，需要按优先级来显示
      let capabilities = [device.wifiCapacity, device.bleCapacity];
      // 先看看是不是有一个状态在连接中，连接中代表是用户手动点击的，证明是要切换到当前这个能力，优先级最高，按这个能力才显示
      const loadingCapacity = capabilities.find(i => i.state === CapacityState.connecting);
      if (loadingCapacity) {
        return loadingCapacity;
      }
      // 先按能力优先级排序
      capabilities = capabilities.sort(sortCapacityUse);
      console.log('capabilities', capabilities);
      let cap = capabilities[0];
      if (cap.name === DeviceCapacityName.ble && cap.state === CapacityState.online) {
        // 蓝牙只是在线的话，也不能作为能力返回，暂时没有这种设计的弹窗
        // eslint-disable-next-line prefer-destructuring
        cap = capabilities[1];
      }
      return cap;
    }
    if (device.bleCapacity) {
      // 纯蓝牙
      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
      return device.bleCapacity!;
    }
    // 单wifi
    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
    return device.wifiCapacity!;
  };

  componentDidMount() {
    // setTimeout(this.showGprsOffline, 1000);
    const { device } = this.props;
    if (!device.groupID && !device.isVirtual) {
      this.handleDeviceCapacityChange({ newCapacity: this.oldCapacity, device: this.oldDevice });
      this.deviceReaction = reaction(
        () => {
          return {
            list: toJS(deviceListModel.data),
          };
        },
        ({ list }: { list: INewDevice[] }) => {
          const newDevice = list.find((i: INewDevice) => isSameDevice(i, device));
          if (newDevice && isDeviceCapacityChange(newDevice, this.oldDevice)) {
            this.oldDevice = newDevice;
            console.log('模板能力变化了');
            // 能力变化了，判断需要显示什么弹窗
            const newCapacity = this.getDeviceCapacity(newDevice);
            // eslint-disable-next-line prefer-destructuring
            const oldCapacity = this.oldCapacity;
            this.handleDeviceCapacityChange({ newCapacity, oldCapacity, device: newDevice });
            this.oldCapacity = newCapacity;
          }
        },
        {
          fireImmediately: true,
          delay: 200,
          equals: (a, b) => {
            if (a !== b || a.list !== b.list || a.list.length !== b.list.length) {
              return false;
            }
            for (let i = 0; i < b.list.length; i++) {
              if (a.list[i] !== b.list[i]) {
                return false;
              }
            }
            return true;
          },
        }
      );
    }
  }

  handleDeviceCapacityChange = ({
    newCapacity,
    oldCapacity,
    device,
  }: {
    newCapacity: IDeviceCapacity;
    device: INewDevice;
    oldCapacity?: IDeviceCapacity;
  }) => {
    // 能力变化了，判断需要显示什么弹窗
    console.log('模板能力变化了', oldCapacity, newCapacity);
    /**
     * GPRS(4G) 是否是GPRS设备取决于productConfig中的m2mProtoc
     * 通过isGPRS判断
     */
    const productsConfig = getConfig();
    const productConfig = productsConfig?.find(p => p.productKey === device.productKey);
    const isGprsProduct = !!productConfig && isGPRS(productConfig);
    // 先检查能不能覆盖弹窗
    if (this.checkCanOver()) {
      // 如果新能力是连接中的话，弹窗
      if (newCapacity?.state === CapacityState.connecting) {
        // eslint-disable-next-line no-unused-expressions
        switch (newCapacity.name) {
          case DeviceCapacityName.ble:
            this.showBleConnecting();
            break;
          case DeviceCapacityName.wifi:
            isGprsProduct ? this.showGprsConnecting() : this.showWifiConnecting();
            break;
          default:
            break;
        }
        return;
      }
      // 如果上一次能力是连接中，但新能力不是同一个且可控的话，代表连接失败，弹窗
      if (
        oldCapacity &&
        oldCapacity.state === CapacityState.connecting &&
        (newCapacity.name !== oldCapacity.name || newCapacity.state !== CapacityState.controllable)
      ) {
        // eslint-disable-next-line no-unused-expressions
        switch (oldCapacity.name) {
          case DeviceCapacityName.ble:
            this.showBleConnectFail();
            break;
          case DeviceCapacityName.wifi:
            isGprsProduct ? this.showGprsConnectFail() : this.showWifiConnectFail();
            break;
          default:
            break;
        }

        return;
      }
      if (newCapacity?.state === CapacityState.inPreparation) {
        isGprsProduct ? this.showGprsConnecting() : this.showWifiConnecting();
        return;
      }
      // 如果新能力是离线的话，弹窗
      if (newCapacity?.state === CapacityState.offline) {
        if (isGprsProduct) {
          this.showGprsOffline();
        } else if (device.bleCapacity && device.wifiCapacity) {
          this.showWifiBleOffline();
        } else {
          // eslint-disable-next-line no-unused-expressions
          newCapacity.name === DeviceCapacityName.ble ? this.showBleOffline() : this.showWifiOffline();
        }
        return;
      }
      this.hideAlert();
    }
  };

  componentWillUnmount() {
    this.deviceReaction && this.deviceReaction();
  }

  // 重试点击
  retryClick = () => {
    // 先判断是蓝牙连接的重试，还是wifi连接的重试
    const { name } = this.state;
    const { device } = this.props;
    const productsConfig = getConfig();
    const productConfig = productsConfig?.find(p => p.productKey === device.productKey);
    const isGprsProduct = !!productConfig && isGPRS(productConfig);
    if (name === DeviceCapacityName.ble) {
      // if (deviceList.sdkBleDevices.findIndex((i) => isSameDevice(i, device)) > -1) {
      //   // 有设备才发起连接
      this.showBleConnecting();
      deviceListModel.connectBleDevice(device).then(res => {
        if (!res || !res.success) {
          this.showBleConnectFail();
        }
      });
      // }
      return;
    }

    // 代表是wifi重试，那就是蓝牙断开连接失败了
    // 先检查是不是蓝牙还连接着，是就发起断开
    if (device.bleCapacity && device.bleCapacity.state === CapacityState.controllable) {
      isGprsProduct ? this.showGprsConnecting() : this.showWifiConnecting();
      deviceListModel.disconnectFakeBleDevice(device).then(res => {
        if (!res || !res.success) {
          isGprsProduct ? this.showGprsConnectFail() : this.showWifiConnectFail();
        }
      });
      return;
    }
    // 蓝牙断开了，那就按wifi实际状态弹窗显示
    if (device.wifiCapacity) {
      if (device.wifiCapacity.state === CapacityState.inPreparation) {
        // wifi不可控就显示wifi订阅中
        isGprsProduct ? this.showGprsConnecting() : this.showWifiConnecting();
        return;
      }
      if (device.wifiCapacity.state === CapacityState.controllable) {
        // 可控就直接隐藏弹窗即可
        this.hideAlert();
        return;
      }
      if (isGprsProduct) {
        /**
         * 先判断是不是4G设备
         * 如果是4G
         * 不需要考虑蓝牙能力(不需要判断是不是双模)
         */
        this.showGprsOffline();
        return;
      }
      if (device.bleCapacity) {
        this.showWifiBleOffline();
        return;
      }
    }

    this.showWifiOffline();
  };

  hideAlert = () => {
    this.setState({
      buttons: [],
      visible: false,
      title: '',
      content: '',
      image: null,
      name: '',
      canOver: true,
    });
  };

  checkCanOver = () => {
    const { canOver } = this.state;
    return canOver;
  };

  showBleConnecting = () => {
    this.setState({
      title: i18n.t('BLUETOOTH_CONNECTING'),
      visible: true,
      content: i18n.t('SURE_BLUETOOTH_OPEN_AND_CLOSED'),
      image: <FrameImage images={[bleGif1, bleGif2, bleGif3]} style={{ width: 90, height: 70 }} />,
      buttons: [],
      canOver: true,
    });
  };

  showBleConnectFail = () => {
    this.setState({
      title: i18n.t('BLUETOOTH_CONNECT_FAIL'),
      visible: true,
      content: i18n.t('BLUETOOTH_CONNECT_FAIL_TIP'),
      image: <Image src={bleFailIcon} style={{ width: 90, height: 90 }} />,
      buttons: this.getButtons(),
      name: DeviceCapacityName.ble,
      canOver: false,
    });
  };

  showBleOffline = () => {
    this.setState({
      title: i18n.t('BLUETOOTH_OFFLINE'),
      visible: true,
      content: i18n.t('BLUETOOTH_CONNECT_FAIL_TIP'),
      image: <Image src={bleOfflineIcon} style={{ width: 90, height: 90 }} />,
      buttons: [],
      canOver: true,
    });
  };

  showGprsConnecting = () => {
    this.setState({
      title: i18n.t('GPRS_CONNECTING'),
      visible: true,
      content: i18n.t('MAKE_SURE_THE_NETWORK_IS_OPEN'),
      image: <FrameImage images={[gprsGif1, gprsGif2, gprsGif3]} style={{ width: 90, height: 90 }} />,
      buttons: [],
      canOver: true,
    });
  };

  showGprsConnectFail = () => {
    this.setState({
      title: i18n.t('GPRS_CONNECT_FAIL'),
      visible: true,
      content: i18n.t('WIFI_OFFLINE_TIP'),
      image: <Image src={gprsFailIcon} style={{ width: 90, height: 90 }} />,
      buttons: this.getButtons(),
      name: DeviceCapacityName.wifi,
      canOver: false,
    });
  };

  showGprsOffline = () => {
    this.setState({
      title: i18n.t('DEVICE_OFFLINE'),
      visible: true,
      content: i18n.t('WIFI_OFFLINE_TIP'),
      image: <Image src={gprsOfflineIcon} style={{ width: 90, height: 90 }} />,
      buttons: [],
      canOver: true,
    });
  };

  showWifiConnecting = () => {
    this.setState({
      title: i18n.t('WIFI_CONNECTING'),
      visible: true,
      content: i18n.t('MAKE_SURE_THE_NETWORK_IS_OPEN'),
      image: <FrameImage images={[wifiGif1, wifiGif2, wifiGif3]} style={{ width: 90, height: 90 }} />,
      buttons: [],
      canOver: true,
    });
  };

  showWifiConnectFail = () => {
    this.setState({
      title: i18n.t('WIFI_CONNECT_FAIL'),
      visible: true,
      content: i18n.t('MAKE_SURE_THE_NETWORK_IS_OPEN'),
      image: <Image src={wifiFailIcon} style={{ width: 90, height: 90 }} />,
      buttons: this.getButtons(),
      name: DeviceCapacityName.wifi,
      canOver: false,
    });
  };

  showWifiOffline = () => {
    this.setState({
      title: i18n.t('WIFI_OFFLINE'),
      visible: true,
      content: i18n.t('WIFI_OFFLINE_TIP'),
      image: <Image src={wifiOfflineIcon} style={{ width: 90, height: 90 }} />,
      buttons: [],
      canOver: true,
    });
  };

  // 双模离线
  showWifiBleOffline = () => {
    this.setState({
      title: i18n.t('DEVICE_OFFLINE'),
      visible: true,
      content: (
        <View>
          <TipItem ponit={false} text={i18n.t('MAKE_SURE_ONE_CONNECT_CAN_USE')} />
          <TipItem text={`${i18n.t('WIFI')}: ${i18n.t('WIFI_OFFLINE_TIP')}`} />
          <TipItem text={`${i18n.t('BLUETOOTH')}: ${i18n.t('BLUETOOTH_CONNECT_FAIL_TIP')}`} />
        </View>
      ),
      image: <Image src={offlineIcon} style={{ width: 110, height: 110 }} />,
      buttons: [],
      canOver: true,
    });
  };

  render() {
    const { device } = this.props;
    const { buttons, visible, title, content, image } = this.state;
    return device && device.groupID ? (
      [
        // 分组按旧的逻辑显示，暂时未定义分组的能力
        <DeviceLoading visible={device.netStatus === 1} key={1} />,
        <DeviceOffline visible={device.isOnline === false} key={2} />,
      ]
    ) : (
      <DeviceStatusModal visible={visible} title={title} content={content} image={image} buttons={buttons} />
    );
  }
}

export default DeviceCapacityModal;
